package com.shfl.component;

import com.shfl.common.ApiResultHelper;
import com.shfl.common.ApiSimpleResultHelper;
import com.shfl.models.*;
import com.shfl.single.SingleUserInfo;
import com.shfl.stock.Stock;
import com.shfl.utils.PropertiesUtil;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.*;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class ToolServiceComponent {

    /**
     * 登陆渠道
     */
    static final Integer clientType = 1;

    static String URL = "";

    public ToolServiceComponent() {
        String url = "";
        String clientType = "";
        try {
            url = PropertiesUtil.getProperty(Stock.proUrl, "project.url");
            clientType = PropertiesUtil.getProperty(Stock.proUrl, "project.clientType");
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.URL = url;
    }


    static final String USER = "api/user/";

    static final String IMAGE_TO_TEXT = "api/imageToText/";

    static final String ACCOUNT = "api/account/";

    static final String GOODS = "/api/goods/";

    static final String ORDER = "/api/order/";

    /**
     * 获取公告
     *
     * @return
     */
    public ApiSimpleResultHelper affiche() {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + USER + "affiche/" + clientType;
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ApiSimpleResultHelper result = new ApiSimpleResultHelper<>();
        try {
            result = restTemplate.getForObject(url, ApiSimpleResultHelper.class);
        } catch (RestClientException e) {
            return restClientException(result);
        }
        return result;
    }

    /**
     * 创建订单
     *
     * @param info
     * @return
     */
    public ApiSimpleResultHelper createOrder(CreateOrderInfo info) {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + ORDER + "create";
        Map<String, Object> map = beanToMap(info);
        HttpHeaders headers = new HttpHeaders();
        headers.set("auth-token", SingleUserInfo.getSingleUserInfo().getTokenInfo().getToken());
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> request = new HttpEntity<Map<String, Object>>(map, headers);
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ApiSimpleResultHelper result = new ApiSimpleResultHelper<>();
        try {
            result = restTemplate.postForObject(url, request, ApiSimpleResultHelper.class);
        } catch (RestClientException e) {
            return restClientException(result);
        }

        return result;

    }

    /**
     * 获取用户信息
     *
     * @return
     */
    public ApiSimpleResultHelper goodsInfo() {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + GOODS + "info/" + clientType;
        HttpHeaders headers = new HttpHeaders();
        headers.set("auth-token", SingleUserInfo.getSingleUserInfo().getTokenInfo().getToken());
        headers.setContentType(MediaType.APPLICATION_JSON);
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        HttpEntity<String> requestEntity = new HttpEntity<String>(null, headers);
        ApiSimpleResultHelper result = new ApiSimpleResultHelper<>();
        try {
            ResponseEntity<ApiSimpleResultHelper> resEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, ApiSimpleResultHelper.class);
            result = resEntity.getBody();
        } catch (RestClientException e) {
            return restClientException(result);
        }
        return result;
    }


    /**
     * 获取账户信息
     *
     * @return
     */
    public ApiSimpleResultHelper account() {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + ACCOUNT + "list/" + clientType;
        HttpHeaders headers = new HttpHeaders();
        headers.set("auth-token", SingleUserInfo.getSingleUserInfo().getTokenInfo().getToken());
        headers.setContentType(MediaType.APPLICATION_JSON);
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        HttpEntity<String> requestEntity = new HttpEntity<String>(null, headers);
        ApiSimpleResultHelper result = new ApiSimpleResultHelper<>();
        try {
            ResponseEntity<ApiSimpleResultHelper> resEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, ApiSimpleResultHelper.class);
            result = resEntity.getBody();
        } catch (RestClientException e) {
            return restClientException(result);
        }
        return result;
    }


    /**
     * 登陆
     *
     * @param info
     * @return
     */
    public ApiSimpleResultHelper login(LoginInfo info) {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + USER + "login";
        Map<String, Object> map = beanToMap(info);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> request = new HttpEntity<Map<String, Object>>(map, headers);
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ApiSimpleResultHelper result = new ApiSimpleResultHelper<>();
        try {
            result = restTemplate.postForObject(url, request, ApiSimpleResultHelper.class);
        } catch (RestClientException e) {
            return restClientException(result);
        }

        return result;
    }


    /**
     * 注册
     *
     * @param info
     * @return
     */
    public ApiResultHelper signIn(@Validated SignInInfo info) {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + USER + "sign/in";
        Map<String, Object> map = beanToMap(info);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> request = new HttpEntity<Map<String, Object>>(map, headers);
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ApiResultHelper result = new ApiResultHelper();
        try {
            result = restTemplate.postForObject(url, request, ApiResultHelper.class);
        } catch (RestClientException e) {
            return restClientException(result);
        }

        return result;
    }

    /**
     * 重置密码
     *
     * @param info
     * @return
     */
    public ApiResultHelper reset(@Validated ResetInfo info) {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + USER + "reset/password";
        Map<String, Object> map = beanToMap(info);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> request = new HttpEntity<Map<String, Object>>(map, headers);
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ApiResultHelper result = new ApiResultHelper();
        try {
            result = restTemplate.postForObject(url, request, ApiResultHelper.class);
        } catch (RestClientException e) {
            return restClientException(result);
        }
        return result;
    }

    /**
     * 发送验证码
     *
     * @param info
     * @return
     */
    public ApiResultHelper seadCode(SendMailInfo info) {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + USER + "send/mail";
        Map<String, Object> map = beanToMap(info);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> request = new HttpEntity<Map<String, Object>>(map, headers);
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ApiResultHelper result = new ApiResultHelper();
        try {
            result = restTemplate.postForObject(url, request, ApiResultHelper.class);
        } catch (RestClientException e) {
            return restClientException(result);
        }
        return result;
    }


    /**
     * 获取文件类容
     *
     * @param info
     * @return
     */
    public ApiSimpleResultHelper auth(ImageToTextInfo info) {
        RestTemplate restTemplate = new RestTemplate();
        String url = URL + IMAGE_TO_TEXT + "auth";
        MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
        param.add("file", new MultipartFileResource(info.getInputStream(), "ImageToText"));
        param.add("recognitionType", info.getRecognitionType());

        HttpHeaders headers = new HttpHeaders();
        headers.set("auth-token", SingleUserInfo.getSingleUserInfo().getTokenInfo().getToken());
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<MultiValueMap<String, Object>>(param, headers);
        //解决乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ApiSimpleResultHelper result = new ApiSimpleResultHelper();
        try {
            result = restTemplate.postForObject(url, request, ApiSimpleResultHelper.class);
        } catch (RestClientException e) {
            e.printStackTrace();
            return restClientException(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private class MultipartFileResource extends InputStreamResource {
        private String filename;

        public MultipartFileResource(InputStream inputStream, String filename) {
            super(inputStream);
            this.filename = filename;
        }

        @Override
        public String getFilename() {
            return this.filename;
        }

        @Override
        public long contentLength() throws IOException {
            return -1; // we do not want to generally read the whole stream into memory ...
        }
    }

    private <T extends ApiResultHelper> T restClientException(T obj) {
        ApiResultHelper apiResultHelper = obj;
        apiResultHelper.setResCode("9999");
        apiResultHelper.setResDesc("请检查网络或联系客服人员!");
        return (T) apiResultHelper;
    }

    /**
     * 对象装换map
     *
     * @param obj
     * @return
     */
    private static Map<String, Object> beanToMap(Object obj) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!key.equals("class") && !key.equals("pageNo") && !key.equals("pageSize")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    map.put(key, value);
                }
            }
        } catch (Exception e) {
            System.out.println("transBean2Map Error " + e);
        }
        map.put("clientType", clientType);
        return map;
    }


}
